//
//  ObjectsAndClasses.swift
//  a_swift_tour
//
//  Created by yao_yu on 14-8-18.
//  Copyright (c) 2014年 yao_yu. All rights reserved.
//

import Foundation


// P26 类和对象
func ClassAndObject(){
    class Shape{
        var numberOfSides = 0
        var klass:String{
            return "Shape"
        }
        func simpleDescription() -> String{
            return "A shape with \(numberOfSides) sides."
        }
    }
    var shape = Shape()
    shape.numberOfSides = 7
    var shapeDescription = shape.simpleDescription()
    
    // P27 类初始化,继承
    class NamedShape:Shape{
        var name:String
        init(name:String){
            self.name = name
        }
    }
    
    // P28 继承,重载(override)
    class Square:NamedShape{
        var sideLength:Double
        init(sideLength:Double, name:String){
            self.sideLength = sideLength
            super.init(name: name)
            numberOfSides = 4
        }
        
        func area() -> Double{
            return sideLength * sideLength
        }
        
        override func simpleDescription() -> String {
            return "A square with sides of length \(sideLength)"
        }
    }
    let test = Square(sideLength: 5.2, name: "My test square")
    //println(test.area())
    //println(test.simpleDescription())
    
    // P30 练习: 圆
    class Circle:NamedShape{
        var radius:Double
        init(radius:Double, name:String){
            self.radius = radius
            super.init(name: name)
        }
        
        var area:Double{
            return 3.1415926 * radius * radius
        }
        
        var diameter:Double{
            return radius + radius
        }
        
        override func simpleDescription() -> String {
            return "A circle with radius of length \(radius)"
        }
    }
    let circle = Circle(radius: 1.0, name: "My test circle")
    var area = circle.area
    var desc = circle.simpleDescription()
    
    // P30 等边三角形
    class EquilateralTriangle:NamedShape{
        var sideLength: Double = 0.0
        init(sideLength:Double, name:String){
            self.sideLength = sideLength
            super.init(name: name)
            numberOfSides = 3
        }
        
        var perimeter:Double{
            get{
                return 3.0 * sideLength
            }
            set{
                sideLength = newValue / 3.0
            }
        }
        override func simpleDescription() -> String {
            return "A equilateral triangle with sides of length \(sideLength)"
        }
    }
    var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
    var perimeter = triangle.perimeter
    triangle.perimeter = 9.9
    // println(triangle.sideLength)
    
    // P32 willSet, didSet
    class TriangleAndSquare{
        var triangle: EquilateralTriangle{
            willSet{
                square.sideLength = newValue.sideLength
            }
        }
        var square:Square{
            willSet{
                triangle.sideLength = newValue.sideLength
            }
        }
        init(size:Double, name:String){
            square = Square(sideLength: size, name: name)
            triangle = EquilateralTriangle(sideLength: size, name: name)
        }
    }
    var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shap")
    //    println(triangleAndSquare.square.sideLength)
    //    println(triangleAndSquare.triangle.sideLength)
    triangleAndSquare.square = Square(sideLength: 50, name: "large square")
    //    println(triangleAndSquare.triangle.sideLength)
    //下面的代码不能影响triangle的变量(局限性)
    triangleAndSquare.square.sideLength = 10
    
    // P34 第二名称
    class Counter{
        var count:Int = 0
        func incrementBy(amount: Int, numberOfTimes times:Int){
            count += amount * times
        }
    }
    var counter = Counter()
    counter.incrementBy(2, numberOfTimes: 7)
    // println(counter.count) // 14
    
    // P35 可选值
    let optionalSquare:Square? = Square(sideLength: 2.5, name: "optional square")
    let sideLength = optionalSquare?.sideLength
    //println(sideLength)
}